﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;

namespace OpenLinkCommon.UnitTest
{
    using Windy.OpenLink;
    using Windy.OpenLink.Names;

    public class NameExtensionTest
    {
        private void AssertNameItem(NameItem item, string name, string extension = null)
        {
            Assert.Equal(name, item.Name);
            Assert.Equal(extension, item.Extension);
        }

        private void AssertNameItemTree(NameItem item, string name, string extension = null, string parent = null, string child = null)
        {
            Assert.Equal(name, item.Name);
            Assert.Equal(extension, item.Extension);
            Assert.Equal(parent, item.Parent.ToFullName());
            Assert.Equal(child, item.Child.ToFullName());
        }


        [Fact()]
        public void ToNameItem()
        {
            AssertNameItem("ABC".ToNameItem(), "ABC");
            AssertNameItem("ABC:BBB".ToNameItem(), "ABC", "BBB");
        }

        [Fact()]
        public void BasicConstruct()
        {
            Assert.Equal("ABC.DEF.HIJ", "ABC".ToNameItem().Child("DEF").Child("HIJ").ToFullName());
        }

        [Fact()]
        public void Parse()
        {
            NameItem item = "ABC.DEF:GGG.WWW".ParseName();

            AssertNameItem(item, "WWW");
            AssertNameItem(item.ToParent(1), "DEF", "GGG");
            AssertNameItem(item.ToParent(2), "ABC");
        }

        [Fact()]
        public void ToFullName()
        {
            var item = "A.B.C.D.E.F.G:H.I.J.K".ParseName();
            Assert.Equal("A.B.C.D.E.F.G:H.I.J.K", item.ToFullName());
            Assert.Equal("A", item.ToParent().ToFullName());
            Assert.Equal("A.B.C.D.E.F.G:H.I.J.K", item.ToChild().ToFullName());
        }

        [Fact()]
        public void ToNodeName()
        {
            string fullName, nodeName;

            fullName = nodeName = "ABC";
            Assert.Equal(fullName, fullName.ToNameItem().ToNodeName());

            fullName = nodeName = "ABC:EEE";
            Assert.Equal(nodeName, fullName.ToNameItem().ToNodeName());

            fullName = "WWW.XXX.ABC:EEE";
            nodeName = "ABC:EEE";
            Assert.Equal(nodeName, fullName.ParseName().ToNodeName());
        }

        [Fact()]
        public void NameItemNavigation()
        {
            NameItem item = "A.B.C.D.E.F.G:H.I.J.K".ParseName();

            AssertNameItemTree(item.ToParent(0), "K", parent: "A.B.C.D.E.F.G:H.I.J");
            AssertNameItemTree(item.ToParent(1), "J", parent: "A.B.C.D.E.F.G:H.I", child: "A.B.C.D.E.F.G:H.I.J.K");
            AssertNameItemTree(item.ToParent(3), "G", "H", "A.B.C.D.E.F", "A.B.C.D.E.F.G:H.I");
            AssertNameItemTree(item.ToParent(), "A", child: "A.B");

            item = item.ToParent();

            AssertNameItemTree(item.ToChild(0), "A", child: "A.B");
            AssertNameItemTree(item.ToChild(1), "B", parent: "A", child: "A.B.C");
            AssertNameItemTree(item.ToChild(3), "D", parent: "A.B.C", child: "A.B.C.D.E");
            AssertNameItemTree(item.ToChild(), "K", parent: "A.B.C.D.E.F.G:H.I.J");

            AssertNameItemTree(item.ToChild(5), item.ToChild(5).Name, item.ToChild(5).Extension, item.ToChild(4).ToFullName(), item.ToChild(6).ToFullName());
        }


        [Fact()]
        public void VerifyName()
        {
            string name;

            name = null;
            Assert.False(name.VerifyNodePrimaryName());
            Assert.True(name.VerifyExtensionName());
            Assert.False(name.VerifyNodeName());
            Assert.False(name.VerifyName());

            name = string.Empty;
            Assert.True(name.VerifyNodePrimaryName());
            Assert.True(name.VerifyExtensionName());
            Assert.True(name.VerifyNodeName());
            Assert.True(name.VerifyName());

            name = "AB";
            Assert.True(name.VerifyNodePrimaryName());
            Assert.True(name.VerifyExtensionName());
            Assert.True(name.VerifyNodeName());
            Assert.True(name.VerifyName());

            name = "AB:BC";
            Assert.False(name.VerifyNodePrimaryName());
            Assert.False(name.VerifyExtensionName());
            Assert.True(name.VerifyNodeName());
            Assert.True(name.VerifyName());

            name = "AB:BC:EE";
            Assert.False(name.VerifyNodePrimaryName());
            Assert.False(name.VerifyExtensionName());
            Assert.False(name.VerifyNodeName());
            Assert.False(name.VerifyName());

            name = "AB.CD";
            Assert.False(name.VerifyNodePrimaryName());
            Assert.False(name.VerifyExtensionName());
            Assert.False(name.VerifyNodeName());
            Assert.True(name.VerifyName());

            name = "AB.CD:EE.WW";
            Assert.False(name.VerifyNodePrimaryName());
            Assert.False(name.VerifyExtensionName());
            Assert.False(name.VerifyNodeName());
            Assert.True(name.VerifyName());

            name = "AC..EE";
            Assert.False(name.VerifyNodePrimaryName());
            Assert.False(name.VerifyExtensionName());
            Assert.False(name.VerifyNodeName());
            Assert.True(name.VerifyName());

            name = "AB.CC:EE";
            Assert.False(name.VerifyNodePrimaryName());
            Assert.False(name.VerifyExtensionName());
            Assert.False(name.VerifyNodeName());
            Assert.True(name.VerifyName());
        }

        [Fact()]
        public void StringChildName()
        {
            Assert.Equal("ABC.BBB", "ABC".Child("BBB"));
            Assert.Equal("ABC:WWW.BBB", "ABC:WWW".Child("BBB"));
            Assert.Equal("ABC.BBB:WWW","ABC".Child("BBB:WWW"));

            Assert.Equal("ABC.BBB:WWW","ABC".ChildExtension("BBB","WWW"));
            Assert.Equal("ABC.WWW","ABC".ChildExtension("WWW"));
        }

        //TODO ADD EXCEPTION THROW UNITTEST
    }
}
